<template>
  <div class="app-container">

    <el-row :gutter="20">
<!--      <el-col :span="8">-->
<!--        <el-input placeholder="输入关键字进行过滤" v-model="search"/>-->
<!--      </el-col>-->
      <el-col :span="16">
        <el-button v-permission="['sys:perm:add']" @click="showAddDialog" icon="el-icon-plus" size="small" type="success" round>新增</el-button>
      </el-col>
    </el-row>

    <el-table
      style="width: 100%;margin-top: 10px;"
      border
      row-key="id"
      :data="tableData"
      :height="tableHeight"
      v-loading="flagTableLoading"
      :expand-row-keys="expandKeys"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
      <el-table-column prop="name" label="名称" min-width="200"/>
      <el-table-column prop="reqUrl" label="API请求URL" show-overflow-tooltip min-width="150"/>
      <el-table-column prop="reqMethod" label="API请求方法"  min-width="105"/>
      <el-table-column prop="perms" label="权限标识"  min-width="120"/>
      <el-table-column prop="vueUrl" label="前端请求URL" show-overflow-tooltip min-width="110"/>
      <el-table-column prop="vueComponent" label="前端资源路径" show-overflow-tooltip min-width="200"/>
      <el-table-column prop="type" label="类型" :formatter="formatterType" min-width="80"/>
      <el-table-column prop="status" label="状态" min-width="80"
                       :formatter="formatterStatus"
                       :filters="[{text: '启用', value: 1},{text: '禁用', value: 0}]"
                       :filter-method="handleFilterStatusTableData"/>
      <el-table-column prop="roles" label="所属角色" min-width="180" :formatter="formatterRoles" />
      <el-table-column prop="sort" label="排序" min-width="50"/>
      <el-table-column prop="icon" label="图标" min-width="180"/>
      <el-table-column prop="createTime" label="更新时间" min-width="180"/>
      <el-table-column label="操作" align="center" fixed="right" min-width="210">
<!--        <template slot="header" slot-scope="scope">-->
<!--          <el-input v-model="search" size="mini" placeholder="输入关键字搜索"/>-->
<!--        </template>-->
        <template slot-scope="scope">
          <el-button @click="handleView(scope.$index, scope.row)" type="primary" size="mini">查看</el-button>
          <el-button v-permission="['sys:perm:update']" @click="handleEdit(scope.$index, scope.row)" type="warning" size="mini">编辑</el-button>
          <el-popconfirm title="删除后无法恢复，确定删除吗？" icon="el-icon-info" icon-color="red"
                         @confirm="handleDelete(scope.$index, scope.row)">
            <el-button v-permission="['sys:perm:del']" slot="reference" type="danger" size="mini">删除</el-button>
          </el-popconfirm>
        </template>
      </el-table-column>

    </el-table>

<!--    /////////////////////////查看对话框/////////////////////////////-->

    <el-dialog title="详情" :visible.sync="flagDialogViewVisible">
      <el-descriptions border>
        <el-descriptions-item label="名称">{{form.name}}</el-descriptions-item>
        <el-descriptions-item label="类型">{{formatterType('','',form.type)}}</el-descriptions-item>
        <el-descriptions-item label="状态">{{formatterStatus('','',form.status)}}</el-descriptions-item>
        <el-descriptions-item label="API请求方法">{{form.reqMethod}}</el-descriptions-item>
        <el-descriptions-item label="API请求URL" :span="2">{{form.reqUrl}}</el-descriptions-item>
        <el-descriptions-item label="前端请求URL">{{form.vueUrl}}</el-descriptions-item>
        <el-descriptions-item label="前端资源路径" :span="2">{{form.vueComponent}}</el-descriptions-item>
        <el-descriptions-item label="图标">{{form.icon}}</el-descriptions-item>
        <el-descriptions-item label="所属角色" :span="2">{{form.roleStr}}</el-descriptions-item>
        <el-descriptions-item label="排序">{{form.sort}}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{form.createTime}}</el-descriptions-item>
      </el-descriptions>
      <div slot="footer" class="dialog-footer">
        <el-button @click="flagDialogViewVisible = false">取 消</el-button>
      </div>
    </el-dialog>

<!--    /////////////////////////新增or编辑对话框/////////////////////////////-->



    <el-dialog :title="flagAddOrEdit?'新增':'编辑'"
               :visible.sync="flagDialogUpdateVisible">
      <el-form :model="form" ref="dialogForm" :rules="formRules">
        <el-form-item label="名称" prop="name" :label-width="formLabelWidth">
          <el-input v-model="form.name" autocomplete="on"/>
        </el-form-item>
        <el-form-item label="类型" prop="type" :label-width="formLabelWidth">
          <el-select v-model="form.type" :disabled="form.type===0 && !flagAddOrEdit" placeholder="请选择类型" style="display: block">
            <el-option key="b1" label="目录" :value="0"/>
            <el-option key="b2" label="菜单" :value="1"/>
            <el-option key="b3" label="按钮" :value="2"/>
          </el-select>
        </el-form-item>
        <el-form-item label="上级菜单" v-show="form.type !== 0" prop="pid" :label-width="formLabelWidth">
          <el-select v-model="form.pid" clearable filterable placeholder="请选择上级资源">
            <el-option v-for="item in TABLE_SOURCE_DATA" :key="'par'+item.id" :label="item.name" :value="item.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="权限标识" prop="perms" v-show="form.type !== 0" :label-width="formLabelWidth">
          <el-input v-model="form.perms" autocomplete="on" placeholder="菜单、按钮类型必填"/>
        </el-form-item>
        <el-form-item label="API请求URL" prop="reqUrl" v-show="form.type !== 0" :label-width="formLabelWidth">
          <el-input v-model="form.reqUrl" autocomplete="on" placeholder="菜单、按钮类型必填"/>
        </el-form-item>
        <el-form-item label="API请求方法" prop="reqMethod" v-show="form.type !== 0" :label-width="formLabelWidth">
          <el-select v-model="form.reqMethod" clearable placeholder="菜单、按钮类型，请选择API请求方法" style="display: block">
            <el-option key="r1" label="GET" value="GET"/>
            <el-option key="r2" label="POST" value="POST"/>
            <el-option key="r3" label="PUT" value="PUT"/>
            <el-option key="r4" label="DELETE" value="DELETE"/>
          </el-select>
        </el-form-item>
        <el-form-item label="前端请求URL" prop="vueUrl" v-show="form.type !== 2" :label-width="formLabelWidth">
          <el-input v-model="form.vueUrl" autocomplete="on" placeholder="目录、菜单类型必填"/>
        </el-form-item>
        <el-form-item label="前端资源路径" prop="vueComponent" v-show="form.type === 1" :label-width="formLabelWidth">
          <el-input v-model="form.vueComponent" autocomplete="on" placeholder="菜单类型必填"/>
        </el-form-item>
        <el-form-item label="状态" :label-width="formLabelWidth">
          <el-select v-model="form.status" placeholder="请选择状态">
            <el-option key="s2" label="启用" :value="1"/>
            <el-option key="s1" label="禁用" :value="0"/>
          </el-select>
        </el-form-item>
        <el-form-item label="所属角色" v-show="form.type !== 0" :label-width="formLabelWidth">
          <el-select v-model="roleActiveArr"  multiple filterable default-first-option
                     placeholder="请选择角色" style="display: block">
            <el-option v-for="item in roleArr" :key="'role'+item.id" :label="item.name" :value="item.id"/>
          </el-select>
        </el-form-item>
        <el-form-item label="图标" prop="icon" :label-width="formLabelWidth">
          <el-input v-model="form.icon" autocomplete="on" />
        </el-form-item>
        <el-form-item label="排序" prop="sort" :label-width="formLabelWidth">
          <el-input v-model.number="form.sort" autocomplete="on" />
        </el-form-item>
        <el-form-item label="更新时间" prop="createTime" :label-width="formLabelWidth">
          <el-input v-model="form.createTime" :disabled="true"/>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="flagDialogUpdateVisible = false">取 消</el-button>
        <el-button @click="handleFromConfirm" type="primary">确 定</el-button>
      </div>
    </el-dialog>

  </div>

</template>

<script>

  import permission from '@/directive/permission/index' // 权限判断指令
  import { isEmpty,isNotEmpty } from '@/utils/validate'

  const handleWrapperTableData = (datas) =>{
    let permissionArr = []
    datas.forEach(r =>{
      if (r.pid === 0) {
        handleWrapperTableSubData(r,datas);
        permissionArr.push(r)
      }else if (r.pid === -1) {
        permissionArr.push(r)
      }
    })
    return permissionArr
  }

  const handleWrapperTableSubData = (parent,datas) => {

    for (let i = 0; i < datas.length; i++) {
      let perm = datas[i];
      let pid = parent.id
      if (perm.pid > 0) {
        if (pid === perm.pid) {
          if (isEmpty(parent.children)) {
            parent.children = [];
          }
          parent.children.push(perm);
          handleWrapperTableSubData(perm,datas);
        }
      }
    }
  }

  export default {
  directives: { permission },
  data() {
    return {
      flagDialogUpdateVisible: false,
      flagDialogViewVisible: false,
      flagTableLoading: false,
      flagAddOrEdit: false, //true:add false:edit
      formLabelWidth: '120px',
      tableHeight: document.body.clientHeight-150,   //实时屏幕高度
      search: "",
      tableData: [],
      TABLE_SOURCE_DATA: [],
      form:{},
      roleArr: [],
      roleActiveArr:[],
      formRules:{
        name: [{required:true,type:'string',message:'名称不能为空'}],
        type: [{required:true,message:'请选择类型',trigger: 'change' }],
        sort: [{type: 'number', message: '请输入数字', trigger: 'blur'}],
        perms: [{required:true,message:'权限标识不能为空', type:'url', trigger: 'blur',
          validator: (rule, val, callback) => {
            if (isEmpty(this.form.type)) {
              this.$refs.dialogForm.validateField('type')
              callback()
            }
            if ([1,2].includes(this.form.type) && isEmpty(val)) {
              callback(new Error('菜单/按钮类型下，权限标识不能为空'));
            }else{
              callback();
            }
          }
        }],
        reqUrl: [{required:true,message:'API请求URL不能为空', type:'url', trigger: 'blur',
          validator: (rule, val, callback) => {
            if (isEmpty(this.form.type)) {
              this.$refs.dialogForm.validateField('type')
              callback()
            }
            if ([1,2].includes(this.form.type) && isEmpty(val)) {
              callback(new Error('菜单/按钮类型下，API请求URL不能为空'));
            }else{
              callback();
            }
          }
        }],
        reqMethod: [{required:true,message:'API请求方法不能为空',trigger: ['blur','change'],type:'enum',enum: ['GET', 'POST', 'PUT','DELETE'],
          validator: (rule, val, callback) => {
            if (isEmpty(this.form.type)) {
              this.$refs.dialogForm.validateField('type')
              callback()
            }
            if ([1,2].includes(this.form.type) && isEmpty(val)) {
              callback(new Error('菜单/按钮类型下，API请求方法不能为空'));
            }else{
              callback();
            }
          }
        }],
        vueUrl: [{type:'url', trigger: 'blur',
          validator: (rule, val, callback) => {
            if (isEmpty(this.form.type)) {
              this.$refs.dialogForm.validateField('type')
              callback()
            }
            if ([0,1].includes(this.form.type) && isEmpty(val)) {
              callback(new Error('目录/菜单类型下，前端请求URL不能为空'))
            }else{
              callback()
            }
          }
        }],
        vueComponent:[{type:'url', trigger: 'blur',
          validator: (rule, val, callback) => {
            if (isEmpty(this.form.type)) {
              this.$refs.dialogForm.validateField('type')
              callback()
            }
            if (this.form.type === 1 && isEmpty(val)) {
              callback(new Error('菜单类型下，前端资源路径不能为空'))
            }else{
              callback()
            }
          }
        }]
      }
    }
  },
  created() {
    this.fetchData()
    this.fetchRoles()
  },
  computed:{
    expandKeys(){
      //数组元素需要为字符类型才能生效,并且设置row-key
      return this.tableData.map(obj=>obj.id+'')
    }
  },
  methods: {
    fetchRoles() {
      this.getRequest("/role/listRoleForAdmin").then(res => {
        if (res.code === 200) {
          this.roleArr = res.content
        }else{
          this.$message({message: res.error, type: 'error'})
        }
      }).catch((error) => {
        this.$message({message: error, type: 'error'})
        this.flagTableLoading = false
      })
    },
    fetchData() {
      this.flagTableLoading = true
      this.postRequest("/permission/menuList",).then(res =>{
        if (res.code === 200) {
          this.TABLE_SOURCE_DATA = res.content
          this.tableData = handleWrapperTableData(res.content)
          // this.expandKeys = this.tableData.map(obj=>obj.id+'')
        }
        this.flagTableLoading = false;
      }).catch((error) => {
        this.$message({message: error, type: 'error'})
        this.flagTableLoading = false
      })
    },
    formatterRoles(row,column,cellValue,index){
      if (isNotEmpty(cellValue)) {
        let roleArr = cellValue.map(r=>r.name)
        return JSON.stringify(roleArr)
      }else{
        return ""
      }
    },
    formatterType(row,column,cellValue,index){
      switch (cellValue) {
        case 0: return "目录"
        case 1: return "菜单"
        case 2: return "按钮"
      }
    },
    formatterStatus(row,column,cellValue,index){
      return cellValue ===1 ? "启用":"禁用"
    },
    handleFilterStatusTableData(value, row, column){
      let property = column['property'];
      return row[property] === value
    },
    showAddDialog(){
      this.form = {status:1}
      this.roleActiveArr = []
      // true:add false:edit
      this.flagAddOrEdit = true
      if (isNotEmpty(this.$refs['dialogForm'])) {
        this.$refs['dialogForm'].resetFields();
      }
      this.flagDialogUpdateVisible = true
    },
    handleView(index, row) {
      this.form = row
      this.form.roleStr = this.form.roles.map(obj=>obj.name)
      this.flagDialogViewVisible = true
    },
    handleEdit(index, row) {
      this.form = this.cloneDeep(row)
      this.roleActiveArr = this.form.roles.map(obj=>obj.id)
      // true:add false:edit
      this.flagAddOrEdit = false
      this.flagDialogUpdateVisible = true
    },
    handleDelete(index, row) {
      this.deleteRequest("/permission/"+row.id).then(res =>{
        if (res.code === 200) {
          this.$message({message: "删除成功", type: 'success'})
          this.fetchData()
        }else{
          this.$message({message: "删除失败", type: 'error'})
        }
      })
    },
    handleFromConfirm(){
      this.$refs["dialogForm"].validate(valid => {
        if (valid) {
          this.form.roles = this.roleActiveArr.map(obj=>{return {id:obj}})
          Reflect.deleteProperty(this.form,'children')
          this.flagDialogUpdateVisible = false
          console.log(this.form)

          if (this.flagAddOrEdit) {
            this.postRequest("/permission",this.form).then(res => {
              if (res.code === 200) {
                this.$message({message: "添加成功", type: 'success'})
                this.flagDialogUpdateVisible = false
                this.fetchData()
              }else{
                this.$message({message: "添加失败", type: 'error'})
              }
            })
          }else{
            this.putRequest("/permission",this.form).then(res => {
              if (res.code === 200) {
                this.$message({message: "更新成功", type: 'success'})
                this.flagDialogUpdateVisible = false
                this.fetchData()
              }else {
                this.$message({message: "更新失败", type: 'error'})
              }
            })
          }
        }else{
          this.$message({message: "请完成表单必填选项", type: 'warning'})
        }
      })
    }
  }
}
</script>
